package happy.diandiankong.api;

import happy.diandiankong.api.resource.*;
import io.dropwizard.Application;
import io.dropwizard.client.JerseyClientBuilder;
import io.dropwizard.configuration.EnvironmentVariableSubstitutor;
import io.dropwizard.configuration.SubstitutingSourceProvider;
import io.dropwizard.db.DataSourceFactory;
import io.dropwizard.forms.MultiPartBundle;
import io.dropwizard.jdbi.DBIFactory;
import io.dropwizard.migrations.MigrationsBundle;
import io.dropwizard.setup.Bootstrap;
import io.dropwizard.setup.Environment;
import org.eclipse.jetty.servlets.CrossOriginFilter;
import org.skife.jdbi.v2.DBI;

import javax.servlet.DispatcherType;
import javax.servlet.FilterRegistration;
import javax.ws.rs.client.Client;
import java.util.EnumSet;

/**
 * Title.
 * <p>
 * Description.
 *
 * @author Bill Lv {@literal <billcc.lv@hotmail.com>}
 * @version 1.0
 * @since 2016-08-09
 */
public class DDKApplication extends Application<DDKConfiguration> {
    public static void main(String[] args) throws Exception {
        new DDKApplication().run(args);
    }

    @Override
    public String getName() {
        return "DDK";
    }

    @Override
    public void initialize(Bootstrap<DDKConfiguration> bootstrap) {
        bootstrap.addBundle(new MultiPartBundle());
        // Enable variable substitution with environment variables
        bootstrap.setConfigurationSourceProvider(
                new SubstitutingSourceProvider(
                        bootstrap.getConfigurationSourceProvider(),
                        new EnvironmentVariableSubstitutor(false)
                )
        );

        // Remark: Swagger bug here
//        bootstrap.addBundle(new SwaggerBundle<KickstarterConfiguration>() {
//            @Override
//            protected SwaggerBundleConfiguration getSwaggerBundleConfiguration(KickstarterConfiguration configuration) {
//                // this would be the preferred way to set up swagger, you can also construct the object here programtically if you want
//                return configuration.swaggerBundleConfiguration;
//            }
//        });

        bootstrap.addBundle(new MigrationsBundle<DDKConfiguration>() {
            @Override
            public DataSourceFactory getDataSourceFactory(DDKConfiguration configuration) {
                return configuration.getDataSourceFactory();
            }
        });

    }

    @Override
    public void run(DDKConfiguration configuration, Environment environment) throws Exception {
        // Enable CORS headers
        final FilterRegistration.Dynamic cors =
                environment.servlets().addFilter("CORS", CrossOriginFilter.class);

        // Configure CORS parameters
        cors.setInitParameter("allowedOrigins", "*");
        cors.setInitParameter("allowedHeaders", "X-Requested-With,Content-Type,Accept,Origin,Authorization,Content-Range,Content-Disposition,Content-Description");
        cors.setInitParameter("allowedMethods", "OPTIONS,GET,PUT,POST,DELETE,HEAD");

        // Add URL mapping
        cors.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), true, "/*");

        DataSourceFactory dataSourceFactory = configuration.getDataSourceFactory();

        final Client client = new JerseyClientBuilder(environment).using(configuration.getJerseyClientConfiguration())
                .build(getName());

        final DBIFactory factory = new DBIFactory();
        DBI dbi = factory.build(environment, dataSourceFactory, "mysql");

        // TODO: add resources here...
        environment.jersey().register(new ImageResource(dbi, configuration.getUploadPath(), configuration.getCompressRatio(), configuration.getCompressTmpPath(), configuration.getDomain()));
        environment.jersey().register(new BlocklyResource());
        environment.jersey().register(new DeviceResource());
        environment.jersey().register(new UserResource(dbi));
        environment.jersey().register(new FaceResource(dbi, configuration.getUploadPath(), configuration.getCompressRatio(), configuration.getCompressTmpPath(), configuration.getDomain()));

    }
}
